package com.autonavi.yunda.yunji.core.engine.handler;

import com.aliyun.oss.OSS;
import com.autonavi.yunda.yunji.common.exception.AmapException;
import com.autonavi.yunda.yunji.common.exception.AmapExceptionCode;
import com.autonavi.yunda.yunji.common.utils.SpringUtil;
import com.autonavi.yunda.yunji.core.engine.exception.EngineException;
import com.autonavi.yunda.yunji.core.engine.exception.EnginePreconditions;
import com.autonavi.yunda.yunji.core.service.dbfactory.OssFactoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

/**
 * oss的groovy脚本执行
 */
@Slf4j
public class OssHandler {

    /**
     * 执行groovy的内容
     *
     * @param ossInstance oss实例
     * @param operate     操作命令
     * @param key         key
     * @param value       value
     * @return 执行命令后的返回结果
     */
    public static Object oss(String ossInstance, String operate, String key, Object value, String ossPath) {
        log.info("ossInstance : {},operate : {},key : {},value : {}", ossInstance, operate, key, value);
        OSS ossClient;
        String bucket;
        OssFactoryService service = SpringUtil.getBean(OssFactoryService.class);
        try {
            ossClient = service.getInstance(ossInstance).getClient();
            bucket = service.getInstance(ossInstance).getBucket();
        } catch (Exception e) {
            log.error("从dbFactoryService获取数据源失败 ossInstance:{}", ossInstance);
            throw new AmapException(AmapExceptionCode.COMMON_SERVER_ERROR, "获取数据源失败");
        }
        try {
            ossPath = ossPath.endsWith("/") ? ossPath : ossPath + "/";
            ossPath = ossPath.startsWith("/") ? ossPath.substring(1) : ossPath;
            switch (operate) {
                case "set":
                    return set(ossClient, key, value.toString(), bucket, ossPath);
                case "get":
                    return get(ossClient, key, bucket, ossPath);
                case "uploadFile":
                    return uploadFile(ossClient, key, value, bucket, ossPath);
                default:
                    throw new AmapException(AmapExceptionCode.COMMON_ILLEGAL_PARAM, "not support oss operate :" + operate);
            }
        } catch (AmapException | EngineException e) {
            throw e;
        } catch (Exception e) {
            throw new AmapException(AmapExceptionCode.COMMON_OSS_ERROR, "oss operate error :" + operate, e);
        }
    }

    public static Object set(OSS ossClient, String key, String val, String bucket, String ossPath) {
        EnginePreconditions.check(val != null, "set值不能为null");
        assert val != null;
        ossClient.putObject(bucket, ossPath + key, new ByteArrayInputStream(val.getBytes()));
        return "1";
    }

    public static Object get(OSS ossClient, String key, String bucket, String ossPath) {
        URL url = ossClient.generatePresignedUrl(bucket, ossPath + key, new Date(System.currentTimeMillis() + 1000L * 60 * 60 * 6));
        return url.toString();
    }

    public static Object uploadFile(OSS ossClient, String key, Object val, String bucket, String ossPath) throws IOException {
        EnginePreconditions.check(val != null, "upload文件不能为空");
        assert val != null;
        InputStream inputStream;
        if (val instanceof MultipartFile) {
            inputStream = ((MultipartFile) val).getInputStream();
        } else if (val instanceof byte[]) {
            inputStream = new ByteArrayInputStream((byte[]) val);
        } else if (val instanceof InputStream) {
            inputStream = (InputStream) val;
        } else {
            throw new AmapException("上传文件只支持 file类型,byte数组,inputStream");
        }
        ossClient.putObject(bucket, ossPath + key, inputStream);
        return "1";
    }
}
